package com.syni.mdd.sjb.community.base.utils;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.syni.mdd.sjb.common.component.utils.common.exception.BusinessException;
import com.syni.mdd.sjb.common.component.utils.common.utils.AppConfig;
import com.syni.mdd.sjb.common.component.utils.common.utils.RestTemplateUtils;
import com.syni.mdd.sjb.common.component.utils.common.utils.StringUtils;
import com.syni.mdd.sjb.common.component.utils.redis.utils.RedisTemplateUtils;
import com.syni.mdd.sjb.community.base.constants.Constants;
import lombok.extern.log4j.Log4j2;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Log4j2
public class OAUtils {


    //获取服务商的token
    public static String getProviderToken() {

        if (RedisTemplateUtils.getRedisTemplate().hasKey(Constants.REDIS_KEY_PROVIDERTOKEN)) {
            String providerToken = RedisTemplateUtils.getRedisTemplate().opsForValue().get(Constants.REDIS_KEY_PROVIDERTOKEN).toString();
            if (providerToken != null) {
                return providerToken;
            }
        }

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("corpid", AppConfig.getProperty("CorpID"));
        paramsMap.put("provider_secret", AppConfig.getProperty("ProviderSecret"));
        String requestBody = RestTemplateUtils.postForEntityForJson("https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token", paramsMap);
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            String provider_access_token = userJson.getString("provider_access_token");
            System.out.println(String.format(" >>>>>>>>>>>>>>>>>>> 获取到的provider_access_token：%s <<<<<<<<<<<<<<<<<<", provider_access_token));
            Integer expires_in = userJson.getInteger("expires_in");
            System.out.println(String.format(" >>>>>>>>>>>>>>>>>>> 获取到的expires_in：%s <<<<<<<<<<<<<<<<<<", expires_in));
            RedisTemplateUtils.getRedisTemplate().opsForValue().set(Constants.REDIS_KEY_PROVIDERTOKEN, provider_access_token, expires_in, TimeUnit.SECONDS);
            return provider_access_token;
        }
        return null;
    }

    //获取AccessToken
    public static String getAccessTokenByPerCode(String corpid, String permanentCode) {
        String cacheKey = Constants.REDIS_KEY_ACCESS_TOKEN_BY_PCODE + corpid;
        if (RedisTemplateUtils.getRedisTemplate().hasKey(cacheKey)) {
            String access_token = RedisTemplateUtils.getRedisTemplate().opsForValue().get(cacheKey).toString();
            if (access_token != null) {
                return access_token;
            }
        }

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("auth_corpid", corpid);
        paramsMap.put("permanent_code", permanentCode);
        String postUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token?suite_access_token=%s", OAUtils.getSuiteAccessToken());
        String responseBody = RestTemplateUtils.postForEntityForJson(postUrl, paramsMap);
        log.info("getAccessTokenByPerCode:" + responseBody);
        if (StringUtils.isNotBlank(responseBody)) {
            JSONObject userJson = JSON.parseObject(responseBody);
            String accessToken = userJson.getString("access_token");
            Integer expiresIn = userJson.getInteger("expires_in");
            if (StringUtils.isNotBlank(accessToken) && expiresIn != null) {
                RedisTemplateUtils.getRedisTemplate().opsForValue().set(cacheKey, accessToken, expiresIn, TimeUnit.SECONDS);
                return accessToken;
            } else {
                log.info("accessToken获取失败：" + userJson);
                return null;
            }
        }
        return null;
    }

    public static boolean deleteAccessTokenByPerCode(String corpid) {
        String cacheKey = Constants.REDIS_KEY_ACCESS_TOKEN_BY_PCODE + corpid;
        if (RedisTemplateUtils.getRedisTemplate().hasKey(cacheKey)) {
            RedisTemplateUtils.delete(cacheKey);
        }
        return true;
    }


    public static String getAccessToken() {
        if (RedisTemplateUtils.getRedisTemplate().hasKey(Constants.REDIS_KEY_ACCESS_TOKEN)) {
            String access_token = RedisTemplateUtils.getRedisTemplate().opsForValue().get(Constants.REDIS_KEY_ACCESS_TOKEN).toString();
            if (access_token != null) {
                return access_token;
            }
        }

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("corpid", AppConfig.getProperty("CorpID"));
        paramsMap.put("corpsecret", AppConfig.getProperty("Secret"));

        String responseBody = RestTemplateUtils.postForEntityForJson("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" +
                AppConfig.getProperty("CorpID") + "&corpsecret=" + AppConfig.getProperty("Secret"), new HashMap<>());
        log.info("accessToken：" + responseBody);
        if (StringUtils.isNotBlank(responseBody)) {
            JSONObject userJson = JSON.parseObject(responseBody);
            if ("0".equals(userJson.getString("errcode"))) {
                String access_token = userJson.getString("access_token");
                log.info(String.format(" >>>>>>>>>>>>>>>>>>> access_token：%s <<<<<<<<<<<<<<<<<<", access_token));
                Integer expires_in = userJson.getInteger("expires_in");
                log.info(String.format(" >>>>>>>>>>>>>>>>>>> 获取到的expires_in：%s <<<<<<<<<<<<<<<<<<", expires_in));
                RedisTemplateUtils.getRedisTemplate().opsForValue().set(Constants.REDIS_KEY_ACCESS_TOKEN, access_token, expires_in, TimeUnit.SECONDS);
                return access_token;
            } else {
                log.info("accessToken获取失败：" + userJson);
                return null;
            }

        }
        return null;
    }

    public static String getSuiteJsapiTicket(String corpid, String perCode) {
        if (RedisTemplateUtils.getRedisTemplate().hasKey(Constants.REDIS_KEY_JSAPI_TICKET + corpid)) {
            String jsapiTicket = RedisTemplateUtils.getRedisTemplate().opsForValue().get(Constants.REDIS_KEY_JSAPI_TICKET + corpid).toString();
            if (jsapiTicket != null) {
                return jsapiTicket;
            }
        }
        String getUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=%s&type=agent_config", OAUtils.getAccessTokenByPerCode(corpid, perCode));
        HttpResponse httpResponse = HttpUtil
                .createGet(getUrl)
                .execute();
        log.info("getSuiteJsapiTicket：" + httpResponse.body());
        JSONObject userJson = JSON.parseObject(httpResponse.body());
        if ("0".equals(userJson.getString("errcode"))) {
            String ticket = userJson.getString("ticket");
            log.info(String.format(" >>>>>>>>>>>>>>>>>>> access_token：%s <<<<<<<<<<<<<<<<<<", ticket));
            Integer expires_in = userJson.getInteger("expires_in");
            log.info(String.format(" >>>>>>>>>>>>>>>>>>> 获取到的expires_in：%s <<<<<<<<<<<<<<<<<<", expires_in));
            RedisTemplateUtils.getRedisTemplate().opsForValue().set(Constants.REDIS_KEY_JSAPI_TICKET + corpid, ticket, expires_in, TimeUnit.SECONDS);
            return ticket;
        } else {
            log.info("accessToken获取失败：" + userJson);
            return null;
        }
    }


    //获取第三方应用凭证
    public static String getSuiteAccessToken() {
        if (RedisTemplateUtils.getRedisTemplate().hasKey(Constants.REDIS_KEY_SUITE_ACCESS_TOKEN)) {
            String suite_access_token = RedisTemplateUtils.getRedisTemplate().opsForValue().get(Constants.REDIS_KEY_SUITE_ACCESS_TOKEN).toString();
            if (suite_access_token != null) {
                return suite_access_token;
            }
        }

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("suite_id", AppConfig.getProperty("SuiteID"));
        paramsMap.put("suite_secret", AppConfig.getProperty("Secret"));
        paramsMap.put("suite_ticket", RedisTemplateUtils.getRedisTemplate().opsForValue()
                .get(Constants.REDIS_KEY_TICKET + AppConfig.getProperty("SuiteID")).toString());
        log.info("正在获取三方应用凭证，suite_id：{},suite_secret:{},suite_ticket:{}", AppConfig.getProperty("SuiteID"),
                AppConfig.getProperty("Secret"), paramsMap.get("suite_ticket"));
        String requestBody = RestTemplateUtils.postForEntityForJson("https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token", paramsMap);
        log.info("requestBody:" + requestBody);
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            String suite_access_token = userJson.getString("suite_access_token");
            if (StringUtils.isBlank(suite_access_token)) {
                throw new BusinessException("业务异常:" + userJson.getString(Constants.ERROR_MSG));
            }
            log.info(String.format(" >>>>>>>>>>>>>>>>>>> suite_access_token：%s <<<<<<<<<<<<<<<<<<", suite_access_token));
            Integer expires_in = userJson.getInteger("expires_in");
            log.info(String.format(" >>>>>>>>>>>>>>>>>>> 获取到的expires_in：%s <<<<<<<<<<<<<<<<<<", expires_in));
            RedisTemplateUtils.getRedisTemplate().opsForValue().set(Constants.REDIS_KEY_SUITE_ACCESS_TOKEN, suite_access_token, expires_in, TimeUnit.SECONDS);
            return suite_access_token;
        }
        return null;
    }

    public static String getRegisterCode() {

        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/service/get_register_code?provider_access_token=%s&" +
                        "state=abc123456987",
                getProviderToken());

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("template_id", "tpl975ba440c02e2708");
        String requestBody = RestTemplateUtils.postForEntityForJson(url, paramsMap);
        //获取错误日志
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            String registerCode = userJson.getString("register_code");
            log.info("获取得到的注册码为：{}", registerCode);
            return registerCode;
        }
        return null;

    }

    //获取预授权码
    public static String getPreAuthCode() {

        String suiteAccessToken = getSuiteAccessToken();
        System.err.println("suiteAccessToken" + "," + suiteAccessToken);
        String requestBody = RestTemplateUtils.getForEntity("https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=" + suiteAccessToken, new HashMap<>());
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            if ("ok".equals(userJson.getString("errmsg"))) {
                String preAuthCode = userJson.getString("pre_auth_code");
                System.out.println(String.format(" >>>>>>>>>>>>>>>>>>> preAuthCode：%s <<<<<<<<<<<<<<<<<<", preAuthCode));
                return preAuthCode;
            }
            System.err.println("####---->getPreAuthCode errMsg:" + userJson.getString("errmsg") + "<----####");
        }
        return null;
    }
    //设置授权配置

    /**
     * @param authType 授权类型：0 正式授权， 1 测试授权。 默认值为0。注意，请确保应用在正式发布后的授权类型为“正式授权”
     * @return
     */
    public static boolean setSessionInfo(Integer authType) {
        String suiteAccessToken = getSuiteAccessToken();
        //获取预授权
        String preAuthCode = getPreAuthCode();
        if (preAuthCode == null) {
            return false;
        }
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("pre_auth_code", preAuthCode);
        Map<String, Object> sessionInfo = new HashMap<>();
        sessionInfo.put("auth_type", authType);
        paramsMap.put("session_info", sessionInfo);
        String requestBody = RestTemplateUtils.postForEntityForJson("https://qyapi.weixin.qq.com/cgi-bin/service/set_session_info?suite_access_token=" + suiteAccessToken, paramsMap);
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            if ("ok".equals(userJson.getString("errmsg"))) {
                return true;
            }
        }
        return false;
    }


    public static JSONObject getPermanentCode(String subId, String authCode) {
        String suiteAccessToken = getSuiteAccessToken();
        String postUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=%s", suiteAccessToken);
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("auth_code", authCode);
        String requestBody = RestTemplateUtils.postForEntityForJson(postUrl, paramsMap);
        log.info("getPermanentCode：" + requestBody);
        if (StringUtils.isNotBlank(requestBody)) {
            JSONObject userJson = JSON.parseObject(requestBody);
            if (userJson.containsKey("permanent_code") && StringUtils.isNotBlank(userJson.getString("permanent_code"))) {
                return userJson;
            }
        }
        return null;
    }

    public static JSONObject getUserDetail3rd(String userTicket) throws IOException {
        String suite_access_token = OAUtils.getSuiteAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/service/getuserdetail3rd?suite_access_token=" + suite_access_token;
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("user_ticket", userTicket);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("getUserDetail3rd：" + responseBody);
        if (StringUtils.isNotBlank(responseBody)) {
            JSONObject jsonObj = JSON.parseObject(responseBody);
            return jsonObj;
        }
        return new JSONObject();
    }

    /**
     * 获取客户群列表
     */
    public static JSONObject groupChatList() {
        String access_token = OAUtils.getAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=" + access_token;
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("limit", 1000);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("groupchatList：" + responseBody);
        if (StringUtils.isNotBlank(responseBody)) {
            JSONObject jsonObj = JSON.parseObject(responseBody);
            return jsonObj;
        }
        return new JSONObject();
    }

    /**
     * 获取客户群列表详情
     */
    public static JSONObject groupChatGet(String chatId) {
        String access_token = OAUtils.getAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=" + access_token;
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("chat_id", chatId);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("groupChatGet：" + responseBody);
        if (StringUtils.isNotBlank(responseBody)) {
            JSONObject jsonObj = JSON.parseObject(responseBody);
            return jsonObj;
        }
        return new JSONObject();
    }

    /**
     * 获取管理添加的外部联系人列表数据
     *
     * @param token  企业token
     * @param userId 管理员userId
     * @return JSONObject
     */
    public static JSONObject getExternalUserList(String token, String userId) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=%s&userid=%s",
                token, userId);
        String responseBody = RestTemplateUtils.getForEntity(url);
        log.info("userid:{},外部联系人列表{}：", userId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    /**
     * 批量获取企业管理员添加的外部联系人，首次调用时传入的cursor为空，返回的jsonObject的cursor非空时需要进行递归处理
     *
     * @param token  token
     * @param userId 企业管理员id
     * @return JSONObject
     */
    public static JSONObject queryExternalUserInfos(String token, String userId, String cursor) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("userid", userId);
        jsonParms.put("cursor", cursor);
        jsonParms.put("limit", 50);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("userid:{},外部联系人详情信息列表{}：", userId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    /**
     * 获取外部联系人的详情信息
     *
     * @param token          企业token
     * @param externalUserId 外部联系人id
     * @param cursor         游标，添加人大于500时该字段非空，需要判断是否已经查询得到，如果是则跳过递归步骤
     * @return JSONObject
     */
    public static JSONObject getExternalUserInfos(String token, String externalUserId, String cursor) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=%s&" +
                "external_userid=%s&cursor=%s", token, externalUserId, cursor);
        String responseBody = RestTemplateUtils.getForEntity(url);
        log.info("externalUserId:{},外部联系人详情信息{}：", externalUserId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }


    /**
     * 获取企业的标签信息
     *
     * @param corpId  企业id
     * @param token   企业token
     * @param tagId   标签id,全量同步时输入null
     * @param groupId 标签组id，全量同步时输入null
     * @return 请求结果
     */
    public static JSONObject queryCompanyTagInfos(String token, List<String> tagId, List<String> groupId, String corpId) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("tag_id", tagId);
        jsonParms.put("group_id", groupId);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("corp:{},标签信息列表：{}：", corpId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    /**
     * 获取企业的群聊数据
     *
     * @param token        企业token
     * @param statusFilter 客户群跟进状态过滤。0 - 所有列表(即不过滤) 1 - 离职待继承 2 - 离职继承中 3 - 离职继承完成
     * @param ownerFilter  群主过滤，携带一个参数，案例： "owner_filter": {"userid_list": ["abel"]},
     * @param corpId       企业id
     * @param limit        分页，默认为50
     * @return 查询结果
     */
    public static JSONObject queryCompanyGroupInfos(String token, Integer statusFilter, Object ownerFilter, String cursor,
                                                    String corpId, Integer limit) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("status_filter", statusFilter);
        jsonParms.put("owner_filter", ownerFilter);
        jsonParms.put("cursor", cursor);
        jsonParms.put("limit", limit);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("corp:{},群聊信息列表：{}：", corpId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    /**
     * 根据chatId获取对应的群聊详情数据
     *
     * @param token  企业token
     * @param chatId 群聊id
     * @return 查询结果
     */
    public static JSONObject getChatInfoById(String token, String chatId) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("chat_id", chatId);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("chatId:{},群聊信息：{}：", chatId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    public static JSONObject getUserCount(String token, List<String> userIds, long beginDaySeconds, long endDaySeconds,
                                          String corpId) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("userid", userIds);
        jsonParms.put("start_time", beginDaySeconds);
        jsonParms.put("end_time", endDaySeconds);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("corpId:{},用户统计数据：{}：", corpId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }

    /**
     * 获取群聊统计数据信息
     *
     * @param token           企业token
     * @param beginDaySeconds 时间区间-开始
     * @param endDaySeconds   时间区间-结束
     * @param corpId          企业id
     * @return JSONObject
     */
    public static JSONObject getChatCount(String token, long beginDaySeconds, long endDaySeconds, String corpId) {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day?access_token=%s",
                token);
        Map<String, Object> jsonParms = new HashMap<>();
        jsonParms.put("day_begin_time", beginDaySeconds);
        jsonParms.put("day_end_time", endDaySeconds);
        String responseBody = RestTemplateUtils.postForEntityForJson(url, jsonParms);
        log.info("corpId:{},群聊统计数据：{}：", corpId, responseBody);
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNotBlank(responseBody)) {
            jsonObj = JSON.parseObject(responseBody);
        }
        return jsonObj;
    }
}
